﻿using Framework.Models;
using Framework.Models.Entities;
using Framework.Repository;
using Framework.Utility.Extensions;
using Framework.Utility.Helper;
using Framework.Utility.ViewModels;
using System.Reflection; 
namespace Framework.Code.FlowWork;

public class FlowHandle
{
    private readonly FlowNotificaiton _flowNotificaiton;
    private readonly IFlowinstanceRepository _flowinstanceRepository;
    private readonly IApprovalRecordRepository _approvalRecordRepository;
    private readonly IFlowinstanceOperationHistoryRepository _flowOptionRepository;
    private readonly IFlowinstanceTransitionHistoryRepository _flowTransitionRepository;

    private static UserCacheModel user = new UserCacheModel()
    {
        UserId = "1",//1301
        UserName = "admin"  //张三
    };

    //private static UserCacheModel user
    //{
    //    //get { return CacheFactory.Cache.Get<UserCacheModel>(CacheKay.SessionUser); }
    //}

    public FlowHandle(FlowNotificaiton flowNotificaiton,
        IFlowinstanceRepository flowinstanceRepository,
        IApprovalRecordRepository approvalRecordRepository,
        IFlowinstanceOperationHistoryRepository flowOptionRepository, 
        IFlowinstanceTransitionHistoryRepository flowTransitionRepository)
    {
        _flowNotificaiton = flowNotificaiton;
        _flowinstanceRepository = flowinstanceRepository;
        _approvalRecordRepository = approvalRecordRepository;
        _flowOptionRepository = flowOptionRepository;
        _flowTransitionRepository = flowTransitionRepository;
    }

    #region 获取节点的流程审批人

    /// <summary>
    /// 寻找下一步的执行人
    /// 一般用于本节点审核完成后，修改流程实例的当前执行人，可以做到通知等功能
    /// </summary>
    /// <returns></returns>
    public string GetFlowNextMakers(FlowRuntime wfruntime, string nodeId)
    {
        var approvalNode = wfruntime.Nodes[nodeId];
        return GetNodeCurrentMarkers(approvalNode, wfruntime.applyUserId);
    }

    /// <summary>
    /// 寻找下一步的执行人
    /// 一般用于本节点审核完成后，修改流程实例的当前执行人，可以做到通知等功能
    /// </summary>
    /// <returns></returns>
    public string GetFlowNextMakers(FlowRuntime wfruntime)
    {
        if (wfruntime.nextNodeId == Define.FlowEndCode) { return string.Empty; }

        string approvalNextId = wfruntime.GetNextApprovalNodeId(wfruntime.currentNodeId);

        if (approvalNextId.IsNullOrWhiteSpace()) { return string.Empty; }

        var approvalNode = wfruntime.Nodes[approvalNextId];

        return GetNodeCurrentMarkers(approvalNode, wfruntime.applyUserId);
    }

    /// <summary>
    /// 获取节点会签审核状态
    /// </summary>
    /// <param name="currentNodeId">会签时，currentNodeId是会签开始节点。这个表示当前正在处理的节点</param>
    /// <param name="tag"></param>
    /// <returns>0 会签开始,1 会签结束</returns>
    public int onGetNodeConfluenceType(FlowRuntime flowRuntime, OptionResultTag tag)
    {
        var forkNode = flowRuntime.currentNode;  //会签节点
        int forkNumber = forkNode.properties.approvers.Count;   //直接与会签节点连接的点，即会签分支数目
        if (tag.Taged == (int)TagState.Ok)
        {
            flowRuntime.confluenceOk++;
        }
        else if (tag.Taged == (int)TagState.No)
        {
            return FlowNodeStatus.Join;
        }
        else if (tag.Taged == (int)TagState.Reject)
        {
            return FlowNodeStatus.Join;
        }

        if (flowRuntime.confluenceOk == forkNumber)
        {
            flowRuntime.confluenceOk = 0;//重置会签次数，为下个节点审批做准备
            flowRuntime.confluenceNo = 0;//重置会签次数，为下个节点审批做准备
            return FlowNodeStatus.Join;
        }
        return FlowNodeStatus.Fork;
    }

    /// <summary>
    /// 寻找该节点执行人
    /// </summary>
    /// <param name="node"></param>
    /// <returns></returns>
    public string GetNodeCurrentMarkers(FlowNode node, string flowinstanceCreateUserId = "")
    {
        string makerList = "";
        if (node.nodeType == (int)FlowNodeType.Start && !string.IsNullOrEmpty(flowinstanceCreateUserId)) //如果是开始节点，通常情况下是驳回到开始了
        {
            makerList = flowinstanceCreateUserId;
        }
        else if (!string.IsNullOrWhiteSpace(node.properties.assigneeType))
        {
            if (node.properties.assigneeType == ApprovalType.all) //所有成员
            {
                makerList = ApprovalType.all;
            }
            else if (node.properties.assigneeType == ApprovalType.user) //指定成员
            {
                makerList = GenericHelpers.ArrayToString(node.properties.approvers.Select(c => c.key), makerList);
            }
            else if (node.properties.assigneeType == ApprovalType.assign_role) //指定角色
            {
                //var users = _revelanceRepository.Get(Define.USERROLE, false, node.properties.approvers);

                //makerList = GenericHelpers.ArrayToString(users, makerList);
            }
            else if (node.properties.assigneeType == ApprovalType.assign_leader)//指定负责人
            {
            }
            else if (node.properties.assigneeType == ApprovalType.assign_org)//指定部门
            {
            }
        }
        else //如果没有设置节点信息，默认所有人都可以审核
        {
            makerList = ApprovalType.all;
        }

        return makerList;
    }

    #endregion 获取节点的流程审批人

    #region 节点流转

    /// <summary>
    ///  流程转到申请人节点
    /// </summary>
    public void onRunToApplyUser(Fw_Flowinstance flowInstance, FlowRuntime wfruntime)
    {
        flowInstance.PreviousId = wfruntime.currentNodeId;
        flowInstance.ActivityId = wfruntime.startNodeId;
        flowInstance.ActivityType = (int)FlowNodeType.Start;
        flowInstance.ActivityName = wfruntime.Nodes[wfruntime.startNodeId]?.nodeName ?? Define.FlowEndTitle;
        flowInstance.MakerList = flowInstance.ApplyUserId;
    }

    /// <summary>
    ///  流程转到下一审批人节点
    /// </summary>
    public void onRunToNextApprovalNode(Fw_Flowinstance flowInstance, FlowRuntime wfruntime)
    {
        //流转到下一步
        flowInstance.PreviousId = flowInstance.ActivityId;
        flowInstance.ActivityId = wfruntime.nextNodeId;
        flowInstance.ActivityType = wfruntime.nextNode?.nodeType ?? (int)FlowNodeType.End;
        flowInstance.ActivityName = wfruntime.nextNode?.nodeName ?? Define.FlowEndTitle;
        flowInstance.MakerList = wfruntime.nextNodeId != Define.FlowEndCode ? GetFlowNextMakers(wfruntime) : flowInstance.ApplyUserId;
    }

    #endregion 节点流转

    #region 获取条件节点的判断条件

    /// <summary>
    /// 获取条件节点的判断条件
    /// </summary>
    /// <remarks>用于流程实例中节点条件的判断</remarks>
    /// <typeparam name="T"></typeparam>
    /// <param name="model"></param>
    /// <param name="jsonFrmData"></param>
    /// <returns></returns>
    public string GetFrmData<T>(T model, string jsonFrmData) where T : class
    {
        if (model == null) { return string.Empty; }
        var confs = Json.ToList<ConditionFrmDataConf>(jsonFrmData);
        if (confs == null || !confs.Any()) { return string.Empty; }

        var dic = new Dictionary<string, string>();
        foreach (PropertyInfo p in model.GetType().GetProperties())
        {
            string name = p.Name.ToLower();
            string value = p.GetValue(model)?.ToString();
            if (!string.IsNullOrEmpty(value) && confs.Any(c => c.fieldName.ToLower() == name))
            {
                dic.Add(name, value);
            }
        }
        return JsonHelper.IsJsonNullOrEmpty(dic.ToJson()) ? string.Empty : dic.ToJson();
    }

    #endregion 获取条件节点的判断条件

    #region 检查审核流程的状态

    /// <summary>
    /// 检查是否有该实例的审批权限
    /// </summary>
    /// <param name="instanceId">实例Id</param>
    /// <returns>true 有权限 false 没有权限</returns>
    public bool CheckApprovalAuth(string instanceId)
    {
        var flowInstance = _flowinstanceRepository.GetByKey(instanceId);
        var makerList = GenericHelpers.StringToArray(flowInstance.MakerList);
        if (makerList.Any(c => c == user.UserId))
        {
            return true;
        }
        return false;
    }

    /// <summary>
    /// 检查是否重复审批
    /// </summary>
    /// <param name="instanceId">实例Id</param>
    /// <returns>true 已审批 false 未审批</returns>
    public bool CheckRepeatApproval(string instanceId)
    {
        var records = from flow in _flowinstanceRepository.EntitiesAsNoTracking
                      join recd in _approvalRecordRepository.EntitiesAsNoTracking
                       on flow.Id equals recd.InstanceId
                      where !flow.IsDeleted
                      select recd;

        if (records.Any(c => c.OperateUserId == user.UserId))
        {
            return true;
        }
        return false;
    }

    #endregion 检查审核流程的状态

    #region 添加记录

    /// <summary>
    /// 工作流程流转记录
    /// </summary>
    public void AddTransHistory(FlowRuntime wfruntime)
    {
        _flowTransitionRepository?.Insert(new Fw_FlowinstanceTransitionHistory
        {
            Id = SnowflakeId.Id,
            InstanceId = wfruntime.flowInstanceId,
            CreateBy = user.UserId + user.UserName,
            FromNodeId = wfruntime.currentNodeId,
            FromNodeName = wfruntime.currentNode.nodeName.ParseToString(),
            FromNodeType = (int)wfruntime.currentNodeType,
            ToNodeId = wfruntime.nextNodeId,
            ToNodeName = wfruntime.nextNode?.nodeName.ParseToString(),
            ToNodeType = wfruntime.nextNode?.nodeType ?? (int)FlowNodeType.End,
            IsFinish = wfruntime.nextNodeId == Define.FlowEndCode ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running,
            TransitionSate = 0
        });
    }

    /// <summary>
    /// 添加 操作记录
    /// </summary>
    public void AddOperationHistory(FlowRuntime wfruntime, OptionResultTag optTag)
    {
        _flowOptionRepository.Insert(new Fw_FlowinstanceOperationHistory
        {
            Id = SnowflakeId.Id,
            InstanceId = wfruntime.flowInstanceId,
            CounterSign = wfruntime.counterSign,
            CurrentNodeId = wfruntime.currentNodeId,
            FrmData = wfruntime.FrmData,
            Taged = optTag.Taged,
            OperateUserId = optTag.UserId,
            OperateUserName = optTag.UserName,
            Content = optTag.Description,
            TagedTime = optTag.TagedTime
        });
    }

    /// <summary>
    /// 添加 审批记录
    /// </summary>
    public void AddApprovalRecordHistory(FlowRuntime wfruntime, OptionResultTag optTag, Action<OptionResultTag> action = null)
    {
        if (action != null)
        {
            action(optTag);
        }
        _approvalRecordRepository.Insert(new Fw_FlowinstanceApprovalRecord
        {
            Id = SnowflakeId.Id,
            InstanceId = wfruntime.flowInstanceId,
            NodeId = wfruntime.currentNodeId,
            ApprovalResult = optTag.Taged,
            ApprovalContent = optTag.Description,
            OperateUserId = optTag.UserId,
            OperateUserName = optTag.UserName,
            OperateTime = optTag.TagedTime
        });
    }

    #endregion 添加记录


    #region 消息通知
    /// <summary>
    /// 发送审批通知邮件
    /// </summary>
    /// <param name="doc"></param>
    /// <param name="approverInfo"></param>
    /// <param name="remark"></param>
    public void SendApprovalNotificaiton(Fw_Flowinstance doc, string remark)
    {

        var approvers = new List<Approver>();//GetAllApprovers(approverInfo);
        #region 添加代理审批人
        //approvers = AddAgentApprovers(doc, approvers);
        #endregion
        var actionDict = _flowNotificaiton.ApprovalNotifyActionDict;
        var documentType = 1;

        if (actionDict.ContainsKey(documentType))
        {
            actionDict[documentType](doc, approvers, remark);
        }
    }



    /// <summary>
    /// 通知三方系统，节点执行情况
    /// </summary>
    public void NotifyThirdParty(HttpClient client, OptionResultTag tag)
    {
        
    }

    #endregion 消息通知
}